home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / msdos / sound.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  15KB  |  704 lines

  1. #define USE_SEAL
  2. //#define USE_ALLEGRO
  3.  
  4. #include "mamalleg.h"
  5. #include "driver.h"
  6. #include <dos.h>
  7. #include <conio.h>
  8. #include "ticker.h"
  9. #ifdef USE_SEAL
  10. #include <audio.h>
  11. #endif
  12.  
  13. #ifdef USE_ALLEGRO
  14.  
  15. /* cut down Allegro size */
  16. BEGIN_DIGI_DRIVER_LIST
  17.    DIGI_DRIVER_SOUNDSCAPE
  18.    DIGI_DRIVER_AUDIODRIVE
  19.    DIGI_DRIVER_WINSOUNDSYS
  20.    DIGI_DRIVER_SB
  21. END_DIGI_DRIVER_LIST
  22.  
  23.  
  24. BEGIN_MIDI_DRIVER_LIST
  25. END_MIDI_DRIVER_LIST
  26.  
  27. #endif
  28.  
  29.  
  30. #ifdef USE_SEAL
  31. /* audio related stuff */
  32. #define SOUND_CHANNELS 2    /* left and right */
  33. HAC hVoice[SOUND_CHANNELS];
  34. LPAUDIOWAVE lpWave[SOUND_CHANNELS];
  35. AUDIOINFO info;
  36. AUDIOCAPS caps;
  37. #endif
  38.  
  39. #ifdef USE_ALLEGRO
  40. SAMPLE *mysample;
  41. int myvoice;
  42. #endif
  43.  
  44.  
  45. static int num_used_opl;
  46. int nominal_sample_rate;
  47. int soundcard,usestereo;
  48. int attenuation = 0;
  49. static int master_volume = 256;
  50.  
  51.  
  52. static int stream_playing;
  53. static INT16 *stream_cache_data;
  54. static int stream_cache_len;
  55. static int stream_cache_stereo;
  56.  
  57.  
  58. int msdos_init_seal (void)
  59. {
  60. #ifdef USE_SEAL
  61.     if (AInitialize() == AUDIO_ERROR_NONE)
  62.         return 0;
  63.     else
  64.         return 1;
  65. #else
  66.     return 0;
  67. #endif
  68. }
  69.  
  70. int msdos_init_sound(void)
  71. {
  72. #ifdef USE_SEAL
  73.     int i;
  74.  
  75.     /* Ask the user if no soundcard was chosen */
  76.     if (soundcard == -1)
  77.     {
  78.         unsigned int k;
  79.  
  80.         printf("\nSelect the audio device:\n");
  81.  
  82.         for (k = 0;k < AGetAudioNumDevs();k++)
  83.         {
  84.             /* don't show the AWE32, it's too slow, users must choose Sound Blaster */
  85.             if (AGetAudioDevCaps(k,&caps) == AUDIO_ERROR_NONE &&
  86.                     strcmp(caps.szProductName,"Sound Blaster AWE32"))
  87.                 printf("  %2d. %s\n",k,caps.szProductName);
  88.         }
  89.         printf("\n");
  90.  
  91.         if (k < 10)
  92.         {
  93.             i = getch();
  94.             soundcard = i - '0';
  95.         }
  96.         else
  97.             scanf("%d",&soundcard);
  98.     }
  99.  
  100.     /* initialize SEAL audio library */
  101.     if (soundcard == 0)     /* silence */
  102.     {
  103.         /* update the Machine structure to show that sound is disabled */
  104.         Machine->sample_rate = 0;
  105.         return 0;
  106.     }
  107.  
  108.     /* open audio device */
  109.     /*                              info.nDeviceId = AUDIO_DEVICE_MAPPER;*/
  110.     info.nDeviceId = soundcard;
  111.     /* always use 16 bit mixing if possible - better quality and same speed of 8 bit */
  112.     info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_MONO | AUDIO_FORMAT_RAW_SAMPLE;
  113.  
  114.     /* use stereo output if supported */
  115.     if (usestereo)
  116.     {
  117.         if (Machine->drv->sound_attributes & SOUND_SUPPORTS_STEREO)
  118.             info.wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_STEREO | AUDIO_FORMAT_RAW_SAMPLE;
  119.     }
  120.  
  121.     info.nSampleRate = Machine->sample_rate;
  122.     if (AOpenAudio(&info) != AUDIO_ERROR_NONE)
  123.     {
  124.         printf("audio initialization failed\n");
  125.         return 1;
  126.     }
  127.  
  128.     AGetAudioDevCaps(info.nDeviceId,&caps);
  129.     logerror("Using %s at %d-bit %s %u Hz\n",
  130.             caps.szProductName,
  131.             info.wFormat & AUDIO_FORMAT_16BITS ? 16 : 8,
  132.             info.wFormat & AUDIO_FORMAT_STEREO ? "stereo" : "mono",
  133.             info.nSampleRate);
  134.  
  135.     /* open and allocate voices, allocate waveforms */
  136.     if (AOpenVoices(SOUND_CHANNELS) != AUDIO_ERROR_NONE)
  137.     {
  138.         printf("voices initialization failed\n");
  139.         return 1;
  140.     }
  141.  
  142.     for (i = 0; i < SOUND_CHANNELS; i++)
  143.     {
  144.         lpWave[i] = 0;
  145.     }
  146.  
  147.     stream_playing = 0;
  148.     stream_cache_data = 0;
  149.     stream_cache_len = 0;
  150.     stream_cache_stereo = 0;
  151.  
  152.     /* update the Machine structure to reflect the actual sample rate */
  153.     Machine->sample_rate = info.nSampleRate;
  154.  
  155.     logerror("set sample rate: %d\n",Machine->sample_rate);
  156.  
  157.     {
  158.         TICKER a,b;
  159.         LONG start,end;
  160.  
  161.  
  162.         if (ACreateAudioVoice(&hVoice[0]) != AUDIO_ERROR_NONE)
  163.             return 1;
  164.  
  165.         if ((lpWave[0] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
  166.         {
  167.             ADestroyAudioVoice(hVoice[0]);
  168.             return 1;
  169.         }
  170.  
  171.         lpWave[0]->wFormat = AUDIO_FORMAT_8BITS | AUDIO_FORMAT_MONO;
  172.         lpWave[0]->nSampleRate = Machine->sample_rate;
  173.         lpWave[0]->dwLength = 3*Machine->sample_rate;
  174.         lpWave[0]->dwLoopStart = 0;
  175.         lpWave[0]->dwLoopEnd = 3*Machine->sample_rate;
  176.         if (ACreateAudioData(lpWave[0]) != AUDIO_ERROR_NONE)
  177.         {
  178.             free(lpWave[0]);
  179.             lpWave[0] = 0;
  180.  
  181.             return 1;
  182.         }
  183.  
  184.         memset(lpWave[0]->lpData,0,3*Machine->sample_rate);
  185.         /* upload the data to the audio DRAM local memory */
  186.         AWriteAudioData(lpWave[0],0,3*Machine->sample_rate);
  187.         APrimeVoice(hVoice[0],lpWave[0]);
  188.         ASetVoiceFrequency(hVoice[0],Machine->sample_rate);
  189.         ASetVoiceVolume(hVoice[0],0);
  190.         AStartVoice(hVoice[0]);
  191.  
  192.         a = ticker();
  193.         /* wait some time to let everything stabilize */
  194.         do
  195.         {
  196.             AUpdateAudioEx(Machine->sample_rate / Machine->drv->frames_per_second);
  197.             b = ticker();
  198.         } while (b-a < TICKS_PER_SEC/10);
  199.  
  200.         a = ticker();
  201.         AGetVoicePosition(hVoice[0],&start);
  202.         do
  203.         {
  204.             AUpdateAudioEx(Machine->sample_rate / Machine->drv->frames_per_second);
  205.             b = ticker();
  206.         } while (b-a < TICKS_PER_SEC);
  207.         AGetVoicePosition(hVoice[0],&end);
  208.  
  209.         nominal_sample_rate = Machine->sample_rate;
  210.         Machine->sample_rate = end - start;
  211.         logerror("actual sample rate: %d\n",Machine->sample_rate);
  212.  
  213.         AStopVoice(hVoice[0]);
  214.         ADestroyAudioData(lpWave[0]);
  215.         free(lpWave[0]);
  216.         lpWave[0] = 0;
  217.         ADestroyAudioVoice(hVoice[0]);
  218.     }
  219.  
  220.  
  221. #if 0
  222.     {
  223.         char *blaster_env;
  224.         /* Get Soundblaster base address from environment variabler BLASTER   */
  225.         /* Soundblaster OPL base port, at some compatibles this must be 0x388 */
  226.  
  227.         if(!getenv("BLASTER"))
  228.         {
  229.             printf("\nBLASTER variable not found, disabling fm sound!\n");
  230.                         No_OPL = options.no_fm = 1;
  231.         }
  232.         else
  233.         {
  234.             blaster_env = getenv("BLASTER");
  235.             BaseSb = i = 0;
  236.             while ((blaster_env[i] & 0x5f) != 0x41) i++;        /* Look for 'A' char */
  237.             while (blaster_env[++i] != 0x20) {
  238.                 BaseSb = (BaseSb << 4) + (blaster_env[i]-0x30);
  239.             }
  240.         }
  241.     }
  242. #endif
  243.  
  244. #endif
  245.  
  246. #ifdef USE_ALLEGRO
  247.     reserve_voices(1,0);
  248.     if (install_sound(DIGI_AUTODETECT,MIDI_NONE,0) != 0)
  249.     {
  250.         logerror("Allegro install_sound error: %s\n",allegro_error);
  251.         return 1;
  252.     }
  253.  
  254.     nominal_sample_rate = Machine->sample_rate;
  255. #endif
  256.  
  257.     num_used_opl = 0;
  258.  
  259.     osd_set_mastervolume(attenuation);    /* set the startup volume */
  260.  
  261.     return 0;
  262. }
  263.  
  264. void msdos_shutdown_sound(void)
  265. {
  266.     if (Machine->sample_rate != 0)
  267.     {
  268.         int chip,n;
  269.  
  270.         for(chip=0;chip<num_used_opl;chip++)
  271.         {
  272.             /* silence the OPL */
  273.             for (n = 0x40;n <= 0x55;n++)
  274.             {
  275.                 osd_opl_control(chip,n);
  276.                 osd_opl_write(chip,0x3f);
  277.             }
  278.             for (n = 0x60;n <= 0x95;n++)
  279.             {
  280.                 osd_opl_control(chip,n);
  281.                 osd_opl_write(chip,0xff);
  282.             }
  283.             for (n = 0xa0;n <= 0xb0;n++)
  284.             {
  285.                 osd_opl_control(chip,n);
  286.                 osd_opl_write(chip,0);
  287.             }
  288.         }
  289.  
  290. #ifdef USE_SEAL
  291.         ACloseVoices();
  292.         ACloseAudio();
  293. #endif
  294.     }
  295. }
  296.  
  297.  
  298.  
  299.  
  300. #define NUM_BUFFERS 3    /* raising this number should improve performance with frameskip, */
  301.                         /* but also increases the latency. */
  302.  
  303. static int voice_pos;
  304. static int audio_buffer_length;
  305.  
  306. /* global sample tracking */
  307. static double samples_per_frame;
  308. static double samples_left_over;
  309. static UINT32 samples_this_frame;
  310.  
  311. int osd_start_audio_stream(int stereo)
  312. {
  313. #ifdef USE_SEAL
  314.     int channel;
  315. #endif
  316.  
  317.     if (stereo) stereo = 1;    /* make sure it's either 0 or 1 */
  318.  
  319.     stream_cache_stereo = stereo;
  320.  
  321.     /* determine the number of samples per frame */
  322.     samples_per_frame = (double)Machine->sample_rate / (double)Machine->drv->frames_per_second;
  323.  
  324.     /* compute how many samples to generate this frame */
  325.     samples_left_over = samples_per_frame;
  326.     samples_this_frame = (UINT32)samples_left_over;
  327.     samples_left_over -= (double)samples_this_frame;
  328.  
  329.     audio_buffer_length = NUM_BUFFERS * samples_per_frame + 20;
  330.  
  331.  
  332.     if (Machine->sample_rate == 0) return 0;
  333.  
  334. #ifdef USE_SEAL
  335.     for (channel = 0;channel <= stereo;channel++)
  336.     {
  337.         if (ACreateAudioVoice(&hVoice[channel]) != AUDIO_ERROR_NONE)
  338.             return 0;
  339.  
  340.         if ((lpWave[channel] = (LPAUDIOWAVE)malloc(sizeof(AUDIOWAVE))) == 0)
  341.         {
  342.             ADestroyAudioVoice(hVoice[channel]);
  343.             return 0;
  344.         }
  345.  
  346.         lpWave[channel]->wFormat = AUDIO_FORMAT_16BITS | AUDIO_FORMAT_MONO | AUDIO_FORMAT_LOOP;
  347.         lpWave[channel]->nSampleRate = nominal_sample_rate;
  348.         lpWave[channel]->dwLength = 2*audio_buffer_length;
  349.         lpWave[channel]->dwLoopStart = 0;
  350.         lpWave[channel]->dwLoopEnd = lpWave[channel]->dwLength;
  351.         if (ACreateAudioData(lpWave[channel]) != AUDIO_ERROR_NONE)
  352.         {
  353.             free(lpWave[channel]);
  354.             lpWave[channel] = 0;
  355.  
  356.             return 0;
  357.         }
  358.  
  359.         memset(lpWave[channel]->lpData,0,lpWave[channel]->dwLength);
  360.         APrimeVoice(hVoice[channel],lpWave[channel]);
  361.         ASetVoiceFrequency(hVoice[channel],nominal_sample_rate);
  362.     }
  363.  
  364.     if (stereo)
  365.     {
  366.         /* SEAL doubles volume for panned channels, so we have to compensate */
  367.         ASetVoiceVolume(hVoice[0],32);
  368.         ASetVoiceVolume(hVoice[1],32);
  369.  
  370.         ASetVoicePanning(hVoice[0],0);
  371.         ASetVoicePanning(hVoice[1],255);
  372.  
  373.         AStartVoice(hVoice[0]);
  374.         AStartVoice(hVoice[1]);
  375.     }
  376.     else
  377.     {
  378.         ASetVoiceVolume(hVoice[0],64);
  379.         ASetVoicePanning(hVoice[0],128);
  380.         AStartVoice(hVoice[0]);
  381.     }
  382. #endif
  383.  
  384. #ifdef USE_ALLEGRO
  385.     mysample = create_sample(16,stereo,nominal_sample_rate,audio_buffer_length);
  386.     if (mysample == 0) return 0;
  387.     myvoice = allocate_voice(mysample);
  388.     voice_set_playmode(myvoice,PLAYMODE_LOOP);
  389.     if (stereo)
  390.     {
  391.         INT16 *buf = mysample->data;
  392.         int p = 0;
  393.         while (p != audio_buffer_length)
  394.         {
  395.             buf[2*p] = (INT16)0x8000;
  396.             buf[2*p+1] = (INT16)0x8000;
  397.             p++;
  398.         }
  399.     }
  400.     else
  401.     {
  402.         INT16 *buf = mysample->data;
  403.         int p = 0;
  404.         while (p != audio_buffer_length)
  405.         {
  406.             buf[p] = (INT16)0x8000;
  407.             p++;
  408.         }
  409.     }
  410.     voice_start(myvoice);
  411. #endif
  412.  
  413.     stream_playing = 1;
  414.     voice_pos = 0;
  415.  
  416.     return samples_this_frame;
  417. }
  418.  
  419. void osd_stop_audio_stream(void)
  420. {
  421. #ifdef USE_SEAL
  422.     int i;
  423. #endif
  424.  
  425.  
  426.     if (Machine->sample_rate == 0) return;
  427.  
  428. #ifdef USE_SEAL
  429.     /* stop and release voices */
  430.     for (i = 0;i < SOUND_CHANNELS;i++)
  431.     {
  432.         if (lpWave[i])
  433.         {
  434.             AStopVoice(hVoice[i]);
  435.             ADestroyAudioData(lpWave[i]);
  436.             free(lpWave[i]);
  437.             lpWave[i] = 0;
  438.             ADestroyAudioVoice(hVoice[i]);
  439.         }
  440.     }
  441. #endif
  442. #ifdef USE_ALLEGRO
  443.     voice_stop(myvoice);
  444.     deallocate_voice(myvoice);
  445.     destroy_sample(mysample);
  446.     mysample = 0;
  447. #endif
  448.  
  449.     stream_playing = 0;
  450. }
  451.  
  452. static void updateaudiostream(void)
  453. {
  454.     extern int throttle;
  455.     INT16 *data = stream_cache_data;
  456.     int stereo = stream_cache_stereo;
  457.     int len = stream_cache_len;
  458.     int buflen;
  459.     int start,end;
  460.  
  461.     if (!stream_playing) return;    /* error */
  462.  
  463.     buflen = audio_buffer_length;
  464.     start = voice_pos;
  465.     end = voice_pos + len;
  466.     if (end > buflen) end -= buflen;
  467.  
  468. #ifdef USE_SEAL
  469.     if (throttle)   /* sync with audio only when speed throttling is not turned off */
  470.     {
  471.         profiler_mark(PROFILER_IDLE);
  472.         for (;;)
  473.         {
  474.             LONG curpos;
  475.  
  476.             AGetVoicePosition(hVoice[0],&curpos);
  477.             if (start < end)
  478.             {
  479.                 if (curpos < start || curpos >= end) break;
  480.             }
  481.             else
  482.             {
  483.                 if (curpos < start && curpos >= end) break;
  484.             }
  485.             AUpdateAudioEx(Machine->sample_rate / Machine->drv->frames_per_second);
  486.         }
  487.         profiler_mark(PROFILER_END);
  488.     }
  489.  
  490.     if (stereo)
  491.     {
  492.         INT16 *bufL,*bufR;
  493.         int p;
  494.  
  495.  
  496.         bufL = (INT16 *)lpWave[0]->lpData;
  497.         bufR = (INT16 *)lpWave[1]->lpData;
  498.         p = start;
  499.         while (p != end)
  500.         {
  501.             if (p >= buflen) p -= buflen;
  502.             bufL[p] = *data++;
  503.             bufR[p] = *data++;
  504.             p++;
  505.         }
  506.     }
  507.     else
  508.     {
  509.         INT16 *buf;
  510.         int p;
  511.  
  512.  
  513.         buf = (INT16 *)lpWave[0]->lpData;
  514.         p = start;
  515.         while (p != end)
  516.         {
  517.             if (p >= buflen) p -= buflen;
  518.             buf[p] = *data++;
  519.             p++;
  520.         }
  521.     }
  522.  
  523.     if (start < end)
  524.     {
  525.         AWriteAudioData(lpWave[0],2*start,2*len);
  526.         if (stereo)
  527.             AWriteAudioData(lpWave[1],2*start,2*len);
  528.     }
  529.     else
  530.     {
  531.         int remain = buflen-start;
  532.         AWriteAudioData(lpWave[0],2*start,2*remain);
  533.         AWriteAudioData(lpWave[0],0,2*(len-remain));
  534.         if (stereo)
  535.         {
  536.             AWriteAudioData(lpWave[1],2*start,2*remain);
  537.             AWriteAudioData(lpWave[1],0,2*(len-remain));
  538.         }
  539.     }
  540. #endif
  541. #ifdef USE_ALLEGRO
  542. {
  543.     if (throttle)   /* sync with audio only when speed throttling is not turned off */
  544.     {
  545.         profiler_mark(PROFILER_IDLE);
  546.         for (;;)
  547.         {
  548.             int curpos;
  549.  
  550.             curpos = voice_get_position(myvoice);
  551.             if (start < end)
  552.             {
  553.                 if (curpos < start || curpos >= end) break;
  554.             }
  555.             else
  556.             {
  557.                 if (curpos < start && curpos >= end) break;
  558.             }
  559.         }
  560.         profiler_mark(PROFILER_END);
  561.     }
  562.  
  563.     if (stereo)
  564.     {
  565.         INT16 *buf = mysample->data;
  566.         int p = start;
  567.         while (p != end)
  568.         {
  569.             if (p >= buflen) p -= buflen;
  570.             buf[2*p] = (*data++ * master_volume / 256) ^ 0x8000;
  571.             buf[2*p+1] = (*data++ * master_volume / 256) ^ 0x8000;
  572.             p++;
  573.         }
  574.     }
  575.     else
  576.     {
  577.         INT16 *buf = mysample->data;
  578.         int p = start;
  579.         while (p != end)
  580.         {
  581.             if (p >= buflen) p -= buflen;
  582.             buf[p] = (*data++ * master_volume / 256) ^ 0x8000;
  583.             p++;
  584.         }
  585.     }
  586. }
  587. #endif
  588.  
  589.     voice_pos = end;
  590.     if (voice_pos == buflen) voice_pos = 0;
  591. }
  592.  
  593. int osd_update_audio_stream(INT16 *buffer)
  594. {
  595.     stream_cache_data = buffer;
  596.     stream_cache_len = samples_this_frame;
  597.  
  598.     /* compute how many samples to generate next frame */
  599.     samples_left_over += samples_per_frame;
  600.     samples_this_frame = (UINT32)samples_left_over;
  601.     samples_left_over -= (double)samples_this_frame;
  602.  
  603.     return samples_this_frame;
  604. }
  605.  
  606.  
  607.  
  608. int msdos_update_audio(void)
  609. {
  610.     if (Machine->sample_rate == 0 || stream_cache_data == 0) return 0;
  611.  
  612.     profiler_mark(PROFILER_MIXER);
  613.  
  614. #ifdef USE_SEAL
  615.     AUpdateAudioEx(Machine->sample_rate / Machine->drv->frames_per_second);
  616. #endif
  617.  
  618.     updateaudiostream();
  619.  
  620.     profiler_mark(PROFILER_END);
  621.  
  622.     return 1;
  623. }
  624.  
  625.  
  626.  
  627.  
  628.  
  629. /* attenuation in dB */
  630. void osd_set_mastervolume(int _attenuation)
  631. {
  632.     float volume;
  633.  
  634.  
  635.     if (_attenuation > 0) _attenuation = 0;
  636.     if (_attenuation < -32) _attenuation = -32;
  637.  
  638.     attenuation = _attenuation;
  639.  
  640.      volume = 256.0;    /* range is 0-256 */
  641.     while (_attenuation++ < 0)
  642.         volume /= 1.122018454;    /* = (10 ^ (1/20)) = 1dB */
  643.  
  644.     master_volume = volume;
  645.  
  646. #ifdef USE_SEAL
  647.     ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,master_volume);
  648. #endif
  649. }
  650.  
  651. int osd_get_mastervolume(void)
  652. {
  653.     return attenuation;
  654. }
  655.  
  656. void osd_sound_enable(int enable_it)
  657. {
  658. #ifdef USE_SEAL
  659.     if (enable_it)
  660.         ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,master_volume);
  661.     else
  662.         ASetAudioMixerValue(AUDIO_MIXER_MASTER_VOLUME,0);
  663. #endif
  664. #ifdef USE_ALLEGRO
  665.     if (enable_it)
  666.         set_volume(255,0);
  667.     else
  668.         set_volume(0,0);
  669. #endif
  670. }
  671.  
  672.  
  673.  
  674. /* linux sound driver opl3.c does a so called tenmicrosec() delay */
  675. static void tenmicrosec(void)
  676. {
  677.     int i;
  678.     for (i = 0; i < 16; i++)
  679.         inportb(0x80);
  680. }
  681.  
  682. //#define MAX_OPLCHIP 2  /* SOUND BLASTER 16 or compatible ?? */
  683. #define MAX_OPLCHIP 1  /* SOUND BLASTER pro compatible ??  */
  684.  
  685. void osd_opl_control(int chip,int reg)
  686. {
  687.     if (Machine->sample_rate == 0) return;
  688.  
  689.     if (chip >= MAX_OPLCHIP ) return;
  690.     tenmicrosec();
  691.     outportb(0x388+chip*2,reg);
  692. }
  693.  
  694. void osd_opl_write(int chip,int data)
  695. {
  696.     if (Machine->sample_rate == 0) return;
  697.  
  698.     if (chip >=MAX_OPLCHIP ) return;
  699.     tenmicrosec();
  700.     outportb(0x389+chip*2,data);
  701.  
  702.     if(chip >= num_used_opl) num_used_opl = chip+1;
  703. }
  704.